{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 20640 entries, 0 to 20639\n",
      "Data columns (total 10 columns):\n",
      "longitude             20640 non-null float64\n",
      "latitude              20640 non-null float64\n",
      "housing_median_age    20640 non-null float64\n",
      "total_rooms           20640 non-null float64\n",
      "total_bedrooms        20433 non-null float64\n",
      "population            20640 non-null float64\n",
      "households            20640 non-null float64\n",
      "median_income         20640 non-null float64\n",
      "median_house_value    20640 non-null float64\n",
      "ocean_proximity       20640 non-null object\n",
      "dtypes: float64(9), object(1)\n",
      "memory usage: 1.6+ MB\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "housing_data = pd.read_csv('./housing.csv')\n",
    "housing_data.head()\n",
    "housing_data.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 16512 entries, 1596 to 20278\n",
      "Data columns (total 12 columns):\n",
      "index                 16512 non-null int64\n",
      "longitude             16512 non-null float64\n",
      "latitude              16512 non-null float64\n",
      "housing_median_age    16512 non-null float64\n",
      "total_rooms           16512 non-null float64\n",
      "total_bedrooms        16352 non-null float64\n",
      "population            16512 non-null float64\n",
      "households            16512 non-null float64\n",
      "median_income         16512 non-null float64\n",
      "median_house_value    16512 non-null float64\n",
      "ocean_proximity       16512 non-null object\n",
      "income_cat            16512 non-null float64\n",
      "dtypes: float64(10), int64(1), object(1)\n",
      "memory usage: 1.6+ MB\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import StratifiedShuffleSplit,train_test_split\n",
    "import numpy as np\n",
    "housing_wiht_id = housing_data.reset_index()\n",
    "housing_wiht_id['income_cat'] = np.ceil(housing_wiht_id['median_income']/1.5)\n",
    "\n",
    "#n_solits:拆分为几组，test_size:测试样本的比例,random_state:相当于randon.seed()\n",
    "split = StratifiedShuffleSplit(n_splits=1,test_size=0.2,random_state=44)\n",
    "#这是一个生成器\n",
    "for train_index , text_index in split.split(housing_wiht_id,housing_wiht_id['income_cat']):\n",
    "    train_set_slice = housing_wiht_id.iloc[train_index]\n",
    "    text_set_slcie = housing_wiht_id.iloc[text_index]\n",
    "train_set_slice.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 16512 entries, 1596 to 20278\n",
      "Data columns (total 11 columns):\n",
      "index                 16512 non-null int64\n",
      "longitude             16512 non-null float64\n",
      "latitude              16512 non-null float64\n",
      "housing_median_age    16512 non-null float64\n",
      "total_rooms           16512 non-null float64\n",
      "total_bedrooms        16352 non-null float64\n",
      "population            16512 non-null float64\n",
      "households            16512 non-null float64\n",
      "median_income         16512 non-null float64\n",
      "ocean_proximity       16512 non-null object\n",
      "income_cat            16512 non-null float64\n",
      "dtypes: float64(9), int64(1), object(1)\n",
      "memory usage: 1.5+ MB\n"
     ]
    }
   ],
   "source": [
    "#将数据集的数据和标签分开\n",
    "housing_labels = train_set_slice['median_house_value'].copy()\n",
    "housing = train_set_slice.drop('median_house_value',axis = 1)\n",
    "housing.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 16512 entries, 1596 to 20278\n",
      "Data columns (total 1 columns):\n",
      "median_house_value    16512 non-null float64\n",
      "dtypes: float64(1)\n",
      "memory usage: 258.0 KB\n"
     ]
    }
   ],
   "source": [
    "housing_labels.to_frame().info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>index</th>\n",
       "      <th>longitude</th>\n",
       "      <th>latitude</th>\n",
       "      <th>housing_median_age</th>\n",
       "      <th>total_rooms</th>\n",
       "      <th>total_bedrooms</th>\n",
       "      <th>population</th>\n",
       "      <th>households</th>\n",
       "      <th>median_income</th>\n",
       "      <th>ocean_proximity</th>\n",
       "      <th>income_cat</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "Empty DataFrame\n",
       "Columns: [index, longitude, latitude, housing_median_age, total_rooms, total_bedrooms, population, households, median_income, ocean_proximity, income_cat]\n",
       "Index: []"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "row = housing[housing.isnull().any(axis = 1)]\n",
    "row.head()\n",
    "#放弃这个属性\n",
    "# row = row.drop('ocean_proximity',axis = 1)\n",
    "#删除空值的行\n",
    "row.dropna(subset =[ 'total_bedrooms'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>index</th>\n",
       "      <th>longitude</th>\n",
       "      <th>latitude</th>\n",
       "      <th>housing_median_age</th>\n",
       "      <th>total_rooms</th>\n",
       "      <th>total_bedrooms</th>\n",
       "      <th>population</th>\n",
       "      <th>households</th>\n",
       "      <th>median_income</th>\n",
       "      <th>income_cat</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1596</th>\n",
       "      <td>1596</td>\n",
       "      <td>-122.10</td>\n",
       "      <td>37.89</td>\n",
       "      <td>21.0</td>\n",
       "      <td>3282.0</td>\n",
       "      <td>653.0</td>\n",
       "      <td>1398.0</td>\n",
       "      <td>601.0</td>\n",
       "      <td>5.2079</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20574</th>\n",
       "      <td>20574</td>\n",
       "      <td>-121.92</td>\n",
       "      <td>38.57</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1320.0</td>\n",
       "      <td>246.0</td>\n",
       "      <td>898.0</td>\n",
       "      <td>228.0</td>\n",
       "      <td>1.9327</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12153</th>\n",
       "      <td>12153</td>\n",
       "      <td>-117.25</td>\n",
       "      <td>33.70</td>\n",
       "      <td>10.0</td>\n",
       "      <td>5156.0</td>\n",
       "      <td>941.0</td>\n",
       "      <td>2294.0</td>\n",
       "      <td>747.0</td>\n",
       "      <td>3.5800</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19575</th>\n",
       "      <td>19575</td>\n",
       "      <td>-120.54</td>\n",
       "      <td>37.68</td>\n",
       "      <td>18.0</td>\n",
       "      <td>335.0</td>\n",
       "      <td>76.0</td>\n",
       "      <td>189.0</td>\n",
       "      <td>67.0</td>\n",
       "      <td>1.2273</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12616</th>\n",
       "      <td>12616</td>\n",
       "      <td>-121.55</td>\n",
       "      <td>38.51</td>\n",
       "      <td>14.0</td>\n",
       "      <td>5490.0</td>\n",
       "      <td>851.0</td>\n",
       "      <td>2415.0</td>\n",
       "      <td>837.0</td>\n",
       "      <td>6.5253</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       index  longitude  latitude  housing_median_age  total_rooms  \\\n",
       "1596    1596    -122.10     37.89                21.0       3282.0   \n",
       "20574  20574    -121.92     38.57                10.0       1320.0   \n",
       "12153  12153    -117.25     33.70                10.0       5156.0   \n",
       "19575  19575    -120.54     37.68                18.0        335.0   \n",
       "12616  12616    -121.55     38.51                14.0       5490.0   \n",
       "\n",
       "       total_bedrooms  population  households  median_income  income_cat  \n",
       "1596            653.0      1398.0       601.0         5.2079         4.0  \n",
       "20574           246.0       898.0       228.0         1.9327         2.0  \n",
       "12153           941.0      2294.0       747.0         3.5800         3.0  \n",
       "19575            76.0       189.0        67.0         1.2273         1.0  \n",
       "12616           851.0      2415.0       837.0         6.5253         5.0  "
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "housing_num = housing.drop('ocean_proximity',axis =1)\n",
    "housing_num.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.5960e+03, -1.2210e+02,  3.7890e+01, ...,  6.0100e+02,\n",
       "         5.2079e+00,  4.0000e+00],\n",
       "       [ 2.0574e+04, -1.2192e+02,  3.8570e+01, ...,  2.2800e+02,\n",
       "         1.9327e+00,  2.0000e+00],\n",
       "       [ 1.2153e+04, -1.1725e+02,  3.3700e+01, ...,  7.4700e+02,\n",
       "         3.5800e+00,  3.0000e+00],\n",
       "       ...,\n",
       "       [ 1.5174e+04, -1.1707e+02,  3.3030e+01, ...,  1.0010e+03,\n",
       "         5.0900e+00,  4.0000e+00],\n",
       "       [ 4.3280e+03, -1.1833e+02,  3.4080e+01, ...,  7.7500e+02,\n",
       "         3.2426e+00,  3.0000e+00],\n",
       "       [ 2.0278e+04, -1.1920e+02,  3.4190e+01, ...,  1.7180e+03,\n",
       "         5.0016e+00,  4.0000e+00]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\n",
    "from sklearn.preprocessing import Imputer \n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")\n",
    "#strategy = 'median'使用中位数补全缺失值\n",
    "imputer = Imputer(strategy = 'median')\n",
    "imputer.fit_transform(housing_num)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n",
      "a =  1\n",
      "b =  None\n",
      "a and b =  None\n"
     ]
    }
   ],
   "source": [
    "def if_not(a = None,b = None):\n",
    "    if a and b:\n",
    "        print(1)\n",
    "        print('a = ',a)\n",
    "        print('b = ', b)\n",
    "        print('a and b = ', (a and b))\n",
    "    \n",
    "    elif not (a and b) :\n",
    "        print(3)\n",
    "        print('a = ',a)\n",
    "        print('b = ',b)\n",
    "        print('a and b = ', (a and b))\n",
    "    else:\n",
    "        print(4)\n",
    "        print('a = ',a)\n",
    "        print('b = ',b)\n",
    "        print('a and b = ', (a and b))\n",
    "if_not(a = 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[3],\n",
       "       [1],\n",
       "       [0],\n",
       "       ...,\n",
       "       [0],\n",
       "       [0],\n",
       "       [4]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.preprocessing import LabelEncoder\n",
    "#将字符转换成整数类型，方便机器训练\n",
    "encoder = LabelEncoder()\n",
    "housing_endcode = encoder.fit_transform(housing['ocean_proximity']).reshape(-1,1)\n",
    "housing_endcode"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import OneHotEncoder\n",
    "#将字符转换成热力串0010\n",
    "oneHotEncoder = OneHotEncoder()\n",
    "array1 = oneHotEncoder.fit_transform(housing_endcode)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0., 0., 0., 1., 0.],\n",
       "       [0., 1., 0., 0., 0.],\n",
       "       [1., 0., 0., 0., 0.],\n",
       "       ...,\n",
       "       [1., 0., 0., 0., 0.],\n",
       "       [1., 0., 0., 0., 0.],\n",
       "       [0., 0., 0., 0., 1.]])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#将稀疏矩阵压缩，变为\n",
    "array1.toarray()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 0, 1, 0],\n",
       "       [0, 1, 0, 0, 0],\n",
       "       [1, 0, 0, 0, 0],\n",
       "       ...,\n",
       "       [1, 0, 0, 0, 0],\n",
       "       [1, 0, 0, 0, 0],\n",
       "       [0, 0, 0, 0, 1]])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#将字符列直接转换成独热编码\n",
    "from sklearn.preprocessing import LabelBinarizer\n",
    "binarizer = LabelBinarizer(sparse_output = True)\n",
    "binarizer.fit_transform(housing['ocean_proximity']).toarray()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.5960e+03, -1.2210e+02,  3.7890e+01, ...,  6.0100e+02,\n",
       "         5.2079e+00,  4.0000e+00],\n",
       "       [ 2.0574e+04, -1.2192e+02,  3.8570e+01, ...,  2.2800e+02,\n",
       "         1.9327e+00,  2.0000e+00],\n",
       "       [ 1.2153e+04, -1.1725e+02,  3.3700e+01, ...,  7.4700e+02,\n",
       "         3.5800e+00,  3.0000e+00],\n",
       "       ...,\n",
       "       [ 1.5174e+04, -1.1707e+02,  3.3030e+01, ...,  1.0010e+03,\n",
       "         5.0900e+00,  4.0000e+00],\n",
       "       [ 4.3280e+03, -1.1833e+02,  3.4080e+01, ...,  7.7500e+02,\n",
       "         3.2426e+00,  3.0000e+00],\n",
       "       [ 2.0278e+04, -1.1920e+02,  3.4190e+01, ...,  1.7180e+03,\n",
       "         5.0016e+00,  4.0000e+00]])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.preprocessing import Imputer as SimpleImputer\n",
    "imputer = SimpleImputer(strategy = 'median')\n",
    "housing_num = housing.drop('ocean_proximity',axis = 1) \n",
    "housing_imputer = imputer.fit_transform(housing_num)\n",
    "housing_imputer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[4, 5, 6, 7]"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def transfrom_columns_to_index(*args):\n",
    "    '''\n",
    "    将表的列名转换成列名表的索引\n",
    "    '''\n",
    "    \n",
    "    return [list(housing.columns).index(col) for col in args]\n",
    "    \n",
    "transfrom_columns_to_index(\"total_rooms\", \"total_bedrooms\", \"population\", \"households\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.5960e+03, -1.2210e+02,  3.7890e+01, ...,  6.0100e+02,\n",
       "         5.2079e+00,  4.0000e+00],\n",
       "       [ 2.0574e+04, -1.2192e+02,  3.8570e+01, ...,  2.2800e+02,\n",
       "         1.9327e+00,  2.0000e+00],\n",
       "       [ 1.2153e+04, -1.1725e+02,  3.3700e+01, ...,  7.4700e+02,\n",
       "         3.5800e+00,  3.0000e+00],\n",
       "       ...,\n",
       "       [ 1.5174e+04, -1.1707e+02,  3.3030e+01, ...,  1.0010e+03,\n",
       "         5.0900e+00,  4.0000e+00],\n",
       "       [ 4.3280e+03, -1.1833e+02,  3.4080e+01, ...,  7.7500e+02,\n",
       "         3.2426e+00,  3.0000e+00],\n",
       "       [ 2.0278e+04, -1.1920e+02,  3.4190e+01, ...,  1.7180e+03,\n",
       "         5.0016e+00,  4.0000e+00]])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#自定义转换器，需要继承的类\n",
    "rooms_ix, bedrooms_ix, population_ix, household_ix = \\\n",
    "[list(housing.columns).index(col) for col in (\"total_rooms\", \"total_bedrooms\", \"population\", \"households\")]\n",
    "from sklearn.base import BaseEstimator,TransformerMixin\n",
    "class CombineAttributes(BaseEstimator,TransformerMixin):\n",
    "    \n",
    "    def __init__(self,dividend_indexs = None,divisor_indexs=None):\n",
    "        '''\n",
    "        增加参数，用于网格搜索\n",
    "        dividend_index:被除数的索引列表\n",
    "        divisor_index:除数的索引列表\n",
    "        '''\n",
    "        self.dividend_indexs = dividend_indexs\n",
    "        self.divisor_indexs = divisor_indexs\n",
    "        \n",
    "    def setColumnsName(self,dividend:str,divisor:str):\n",
    "        '''\n",
    "        把被除数和除数合成列名\n",
    "        '''\n",
    "        return '{}_{}'.format(dividend,divisor)\n",
    "#     \n",
    "\n",
    "    \n",
    "    def fit(self,X,y = None):\n",
    "        '''\n",
    "        fit方法中对特征进行分析拟合\n",
    "        '''\n",
    "        return self\n",
    "    \n",
    "    def transform(self,X,y = None):\n",
    "        '''\n",
    "        transform中对数据进行处理\n",
    "        total_bedrooms/total_rooms:卧室在所有房屋所占的比例（富豪的房子功能性房间多，卧室相对少）\n",
    "        total_rooms/population:每个人所拥有的房间（在房子价格高的地方，每人所拥有的房间数变少）\n",
    "        total_rooms/households: 每个家庭所拥有的平均房间数（同上面的关系）\n",
    "        population/households:每个家庭的平均人数（如果房价不高，房子充足，家庭中每个人都应该拥有自己的房子\n",
    "        '''\n",
    "        try:\n",
    "            \n",
    "            if isinstance(X,np.ndarray):\n",
    "                last_X = X\n",
    "#                 for dividend_index in self.dividend_indexs:\n",
    "#                     for divisor_index in self.divisor_indexs:\n",
    "#                         new_columns = self.setColumnsName(dividend_index,divisor_index) \n",
    "                if not (self.dividend_indexs and self.divisor_indexs):\n",
    "                    last_X = np.c_[last_X,X[:,self.dividend_indexs]/X[:,self.divisor_indexs]]\n",
    "                return last_X\n",
    "            elif isinstance(X,pd.DataFrame):\n",
    "                X['bedrooms_per_rooms'] = X['total_bedrooms']/X['total_rooms']\n",
    "                X['bedrooms_per_room'] = X['total_rooms']/X['population']\n",
    "                X['rooms_per_household'] = X['total_rooms']/X['households']\n",
    "                X['population_per_household'] = X['population']/X['households']\n",
    "                return X\n",
    "        except:\n",
    "#             print('%s is not numpy.ndarray and pandas.DataFrame'%X)\n",
    "            return X\n",
    "        \n",
    "divi_s = transfrom_columns_to_index(\"total_rooms\", \"total_bedrooms\", \"population\", \"households\")\n",
    "combina = CombineAttributes()\n",
    "combina.fit_transform(housing_imputer)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "median_house_value    0.049686\n",
       "Name: total_bedrooms, dtype: float64"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "corr_matrix =  housing_data.corr()\n",
    "corr_matrix\n",
    "corr_matrix['median_house_value':]['total_bedrooms']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>37.89</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>38.57</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>33.70</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>37.68</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>38.51</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16507</th>\n",
       "      <td>37.35</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16508</th>\n",
       "      <td>33.90</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16509</th>\n",
       "      <td>33.03</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16510</th>\n",
       "      <td>34.08</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16511</th>\n",
       "      <td>34.19</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>16512 rows × 1 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "           0\n",
       "0      37.89\n",
       "1      38.57\n",
       "2      33.70\n",
       "3      37.68\n",
       "4      38.51\n",
       "...      ...\n",
       "16507  37.35\n",
       "16508  33.90\n",
       "16509  33.03\n",
       "16510  34.08\n",
       "16511  34.19\n",
       "\n",
       "[16512 rows x 1 columns]"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.DataFrame(housing_imputer[:,2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "#将对应列名的列\n",
    "class GetColumns(BaseEstimator,TransformerMixin):\n",
    "    def __init__(self,columns):\n",
    "        self.columns = columns\n",
    "    \n",
    "    def fit(self,X,y = None):\n",
    "        return self\n",
    "    \n",
    "    def transform(self,X,y = None):\n",
    "        if isinstance(X.columns[0],str ):\n",
    "            return X[self.columns]\n",
    "        else:\n",
    "            columns_l = list(housing[self.columns])\n",
    "            self.columns = [columns_l.index(i) for i in columns_l]\n",
    "            return X[self.columns]\n",
    "# housing[list(housing.columns)].head()\n",
    "# ocean_proximity\n",
    "# housing_num.columns\n",
    "# getColumns = GetColumns(housing_num.columns)\n",
    "# getColumns.fit_transform(pd.DataFrame(housing_prepared))\n",
    "# list(housing[self.columns]).index()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "      <th>3</th>\n",
       "      <th>4</th>\n",
       "      <th>5</th>\n",
       "      <th>6</th>\n",
       "      <th>7</th>\n",
       "      <th>8</th>\n",
       "      <th>9</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1596.0</td>\n",
       "      <td>-122.10</td>\n",
       "      <td>37.89</td>\n",
       "      <td>21.0</td>\n",
       "      <td>3282.0</td>\n",
       "      <td>653.0</td>\n",
       "      <td>1398.0</td>\n",
       "      <td>601.0</td>\n",
       "      <td>5.2079</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>20574.0</td>\n",
       "      <td>-121.92</td>\n",
       "      <td>38.57</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1320.0</td>\n",
       "      <td>246.0</td>\n",
       "      <td>898.0</td>\n",
       "      <td>228.0</td>\n",
       "      <td>1.9327</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>12153.0</td>\n",
       "      <td>-117.25</td>\n",
       "      <td>33.70</td>\n",
       "      <td>10.0</td>\n",
       "      <td>5156.0</td>\n",
       "      <td>941.0</td>\n",
       "      <td>2294.0</td>\n",
       "      <td>747.0</td>\n",
       "      <td>3.5800</td>\n",
       "      <td>3.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>19575.0</td>\n",
       "      <td>-120.54</td>\n",
       "      <td>37.68</td>\n",
       "      <td>18.0</td>\n",
       "      <td>335.0</td>\n",
       "      <td>76.0</td>\n",
       "      <td>189.0</td>\n",
       "      <td>67.0</td>\n",
       "      <td>1.2273</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>12616.0</td>\n",
       "      <td>-121.55</td>\n",
       "      <td>38.51</td>\n",
       "      <td>14.0</td>\n",
       "      <td>5490.0</td>\n",
       "      <td>851.0</td>\n",
       "      <td>2415.0</td>\n",
       "      <td>837.0</td>\n",
       "      <td>6.5253</td>\n",
       "      <td>5.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         0       1      2     3       4      5       6      7       8    9\n",
       "0   1596.0 -122.10  37.89  21.0  3282.0  653.0  1398.0  601.0  5.2079  4.0\n",
       "1  20574.0 -121.92  38.57  10.0  1320.0  246.0   898.0  228.0  1.9327  2.0\n",
       "2  12153.0 -117.25  33.70  10.0  5156.0  941.0  2294.0  747.0  3.5800  3.0\n",
       "3  19575.0 -120.54  37.68  18.0   335.0   76.0   189.0   67.0  1.2273  1.0\n",
       "4  12616.0 -121.55  38.51  14.0  5490.0  851.0  2415.0  837.0  6.5253  5.0"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#使用中位数补全缺失值\n",
    "# newdata = pd.DataFrame(imputer.fit_transform(housing_num),columns = housing_num.columns,index = housing.index)\n",
    "# newdata.info()\n",
    "from sklearn.base import BaseEstimator,TransformerMixin\n",
    "class TransfromDataFrame(BaseEstimator,TransformerMixin):\n",
    "    \n",
    "    def __init__(self,data,needColumns = False,needIndex = False):\n",
    "        self.data = data\n",
    "        self.needColumns = needColumns\n",
    "        self.needIndex = needIndex\n",
    "    \n",
    "    def fit(self,ndarray,y = None):\n",
    "        return self\n",
    "    \n",
    "    def transform(self,ndarray,y = None):\n",
    "        if self.needColumns :\n",
    "            if self.needIndex:\n",
    "                return pd.DataFrame(ndarray,columns =self.data.columns,index = self.data.index )\n",
    "            else :\n",
    "                return pd.DataFrame(ndarray,columns =self.data.columns)\n",
    "        else:\n",
    "            if self.needIndex:\n",
    "                return pd.DataFrame(ndarray,index = self.data.index )\n",
    "            else :\n",
    "                return pd.DataFrame(ndarray)\n",
    "           \n",
    "    \n",
    "transformDataFrame = TransfromDataFrame(housing_num)\n",
    "transformDataFrame.fit_transform(imputer.fit_transform(housing_num)).head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-1.46133146, -1.26770359,  1.06016081, ...,  0.26279118,\n",
       "         0.70560872,  0.69592596],\n",
       "       [ 1.72414337, -1.17778278,  1.37854762, ..., -0.7107176 ,\n",
       "        -1.02139381, -0.83878249],\n",
       "       [ 0.31067074,  1.1551628 , -0.90166383, ...,  0.64384287,\n",
       "        -0.15277777, -0.07142826],\n",
       "       ...,\n",
       "       [ 0.81774838,  1.24508361, -1.21536848, ...,  1.30676842,\n",
       "         0.64344042,  0.69592596],\n",
       "       [-1.00276273,  0.61563791, -0.72374178, ...,  0.71692128,\n",
       "        -0.33068771, -0.07142826],\n",
       "       [ 1.6744595 ,  0.18102064, -0.67223803, ...,  3.17809763,\n",
       "         0.59682738,  0.69592596]])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#转换流水线\n",
    "\n",
    "from sklearn.pipeline import Pipeline\n",
    "from sklearn.preprocessing import StandardScaler,LabelBinarizer,Imputer\n",
    "divi_s = transfrom_columns_to_index(\"total_rooms\", \"total_bedrooms\", \"population\", \"households\")\n",
    "pipeline_num = Pipeline([\n",
    "    ('getColumns1',GetColumns(housing_num.columns)),\n",
    "    #中位数补全缺失值\n",
    "    ('imputer',Imputer(strategy = 'median')),\n",
    "    #将numpy数组转成DataFrame\n",
    "#     ( 'transformDataFrame',TransfromDataFrame(data = housing_num,needColumns = False)),\n",
    "    #组合特征\n",
    "    ('combina',CombineAttributes()),\n",
    "    #数据缩放\n",
    "    ('standar',StandardScaler()),\n",
    "#     ( 'transformDataFrame2',TransfromDataFrame(data = housing_num))\n",
    "])\n",
    "pipeline_num.fit_transform(housing)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 0, 1, 0],\n",
       "       [0, 1, 0, 0, 0],\n",
       "       [1, 0, 0, 0, 0],\n",
       "       ...,\n",
       "       [1, 0, 0, 0, 0],\n",
       "       [1, 0, 0, 0, 0],\n",
       "       [0, 0, 0, 0, 1]])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.preprocessing import LabelBinarizer\n",
    "# binarizer = LabelBinarizer(sparse_output = True)\n",
    "# binarizer.fit_transform(housing['ocean_proximity'])\n",
    "class MLabelBinarizer(BaseEstimator,TransformerMixin):\n",
    "  \n",
    "    def __init__(self,sparse_output = True):\n",
    "        self.sparse_output = sparse_output\n",
    "        self.encode = LabelBinarizer()\n",
    "    \n",
    "    def fit(self,data,y = None):\n",
    "        self.encode.fit(data)\n",
    "        return self\n",
    "    \n",
    "    def transform(self,data,y = None):\n",
    "        return self.encode.transform(data)\n",
    "    \n",
    "pipeline_encode = Pipeline([\n",
    "    ('getColumns2',GetColumns('ocean_proximity')),\n",
    "    ('mbinarizer',MLabelBinarizer(sparse_output = True)),\n",
    "#     ('transformDataFrame3',TransfromDataFrame(data = housing_num))\n",
    "])\n",
    "pipeline_encode.fit_transform(housing)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(16512, 15)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#两条流水线并行执行，将最后的数据合并到一起\n",
    "from sklearn.pipeline import FeatureUnion\n",
    "full_pipeline = FeatureUnion(transformer_list=[\n",
    "    ('pipeline_num',pipeline_num),\n",
    "    ('pipeline_encode',pipeline_encode)\n",
    "])\n",
    "housing_prepared = full_pipeline.fit_transform(housing)\n",
    "housing_prepared.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 16512 entries, 0 to 16511\n",
      "Data columns (total 15 columns):\n",
      "0     16512 non-null float64\n",
      "1     16512 non-null float64\n",
      "2     16512 non-null float64\n",
      "3     16512 non-null float64\n",
      "4     16512 non-null float64\n",
      "5     16512 non-null float64\n",
      "6     16512 non-null float64\n",
      "7     16512 non-null float64\n",
      "8     16512 non-null float64\n",
      "9     16512 non-null float64\n",
      "10    16512 non-null float64\n",
      "11    16512 non-null float64\n",
      "12    16512 non-null float64\n",
      "13    16512 non-null float64\n",
      "14    16512 non-null float64\n",
      "dtypes: float64(15)\n",
      "memory usage: 1.9 MB\n"
     ]
    }
   ],
   "source": [
    "# transformDataFrame4=TransfromDataFrame(data = housing)\n",
    "# transformDataFrame4.fit_transform(full_pipeline.fit_transform(housing))\n",
    "housing_prepared = pd.DataFrame(housing_prepared)\n",
    "housing_prepared.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 16512 entries, 1596 to 20278\n",
      "Data columns (total 1 columns):\n",
      "median_house_value    16512 non-null float64\n",
      "dtypes: float64(1)\n",
      "memory usage: 258.0 KB\n"
     ]
    }
   ],
   "source": [
    "housing_labels.to_frame().info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 训练数据模型，评估数据集"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 选择算法来进行训练数据集的训练"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 线性模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.linear_model import LinearRegression\n",
    "lin_reg = LinearRegression()\n",
    "lin_reg.fit(housing_prepared,housing_labels)\n",
    "# housing_prepared.shape\n",
    "# housing_prepared.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 16512 entries, 1596 to 20278\n",
      "Data columns (total 1 columns):\n",
      "median_house_value    16512 non-null float64\n",
      "dtypes: float64(1)\n",
      "memory usage: 258.0 KB\n"
     ]
    }
   ],
   "source": [
    "housing_labels.to_frame().info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([277674.20746716,  60852.69351556, 178384.36804429,  39699.49788595,\n",
       "       241824.82486402])"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#预测前5条数据\n",
    "real_five = housing_labels.iloc[:5]\n",
    "pre_five = housing.iloc[:5]\n",
    "pre_five = full_pipeline.transform(pre_five)\n",
    "lin_reg.predict(pre_five)\n",
    "# pre_five.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1596     310300.0\n",
       "20574    193800.0\n",
       "12153    113400.0\n",
       "19575     87500.0\n",
       "12616    216800.0\n",
       "Name: median_house_value, dtype: float64"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "real_five = housing_labels.iloc[:5]\n",
    "real_five"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "#sklearn.metrics.mean_squared_error(y_true, y_pred, sample_weight=None, multioutput=’uniform_average’)\n",
    "#参数：\n",
    "#y_true：真实值。\n",
    "#y_pred：预测值。\n",
    "#sample_weight：样本权值。\n",
    "#multioutput：多维输入输出，默认为’uniform_average’，计算所有元素的均方误差，\n",
    "#返回为一个标量；也可选‘raw_values’，计算对应列的均方误差，返回一个与列数相等的一维数组。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "68248.68196223066"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#计算均方根误差\n",
    "from sklearn.metrics import mean_squared_error as msque\n",
    "line_mse = msque(housing_labels,lin_reg.predict(housing_prepared))\n",
    "np.sqrt(line_mse)\n",
    "#66008.46112511118\n",
    "#误差过大：模型误差，数据质量问题"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 决策树\n",
    "**在分类问题中，表示基于特征对实例进行分类的过程，可以认为是if-then的集合，也可以认为是定义在特征空间与\n",
    "类空间上的条件概率分布。所以我们可以使用决策树进行一些基于样本而获取目标需求的概率分布情况**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DecisionTreeRegressor(criterion='mse', max_depth=None, max_features=None,\n",
       "                      max_leaf_nodes=None, min_impurity_decrease=0.0,\n",
       "                      min_impurity_split=None, min_samples_leaf=1,\n",
       "                      min_samples_split=2, min_weight_fraction_leaf=0.0,\n",
       "                      presort=False, random_state=42, splitter='best')"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.tree import DecisionTreeRegressor\n",
    "dtree_reg = DecisionTreeRegressor(random_state = 42)\n",
    "dtree_reg.fit(housing_prepared,housing_labels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.0"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tree_predict = dtree_reg.predict(housing_prepared)\n",
    "line_mse = msque(housing_labels,tree_predict)\n",
    "np.sqrt(line_mse)\n",
    "#0.0\n",
    "#存在过度拟合\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 使用交叉验证  \n",
    "**将数据集分为n个组，循环取一个组作为测试集与其他组进行比较**   \n",
    "[cross_val_score的参数设置](https://scikit-learn.org/stable/modules/model_evaluation.html#scoring-parameter)  \n",
    "**测量模型与数据之间距离的度量metrics.mean_squared_error可作为neg_mean_squared_error获得，该度量返回度量的取反值**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([66430.91388452, 68333.9421361 , 65041.81240675, 64291.43715058,\n",
       "       65511.93698851, 69090.28188391, 63757.54799064, 63354.4239245 ,\n",
       "       61880.44283918, 62736.40991038])"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.model_selection import cross_val_score\n",
    "cvs = cross_val_score(dtree_reg,housing_prepared,housing_labels,\n",
    "                     scoring = 'neg_mean_squared_error',cv=10)\n",
    "np.sqrt(-cvs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "def show_tree(cvs):\n",
    "    '''\n",
    "    标准差，中位数，波动值\n",
    "    '''\n",
    "    \n",
    "    print('score',cvs.tolist())\n",
    "    print('mean',cvs.mean())\n",
    "    print('std',cvs.std())\n",
    "# show_tree(np.sqrt(-cvs))   \n",
    "#也不合格"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 随机森林  \n",
    "[RandomForestRegressor](https://blog.csdn.net/chaochaopang0/article/details/78604014)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "RandomForestRegressor(bootstrap=True, criterion='mse', max_depth=None,\n",
       "                      max_features='auto', max_leaf_nodes=None,\n",
       "                      min_impurity_decrease=0.0, min_impurity_split=None,\n",
       "                      min_samples_leaf=1, min_samples_split=2,\n",
       "                      min_weight_fraction_leaf=0.0, n_estimators=10,\n",
       "                      n_jobs=None, oob_score=False, random_state=42, verbose=0,\n",
       "                      warm_start=False)"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.ensemble import RandomForestRegressor\n",
    "forest_reg = RandomForestRegressor(n_estimators = 10,random_state = 42)\n",
    "forest_reg.fit(housing_prepared,housing_labels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "20919.017110860426"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "forest_predict = forest_reg.predict(housing_prepared)\n",
    "forest_mse = msque(housing_labels,forest_predict)\n",
    "np.sqrt(forest_mse)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>294420.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>158440.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>119460.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>84320.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>240280.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          0\n",
       "0  294420.0\n",
       "1  158440.0\n",
       "2  119460.0\n",
       "3   84320.0\n",
       "4  240280.0"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.DataFrame(forest_predict).head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "score [50474.394652871226, 51236.601470640686, 49419.81655285319, 48242.71515768274, 47705.05096393601, 53321.92581090825, 48672.46835075853, 50283.646136468495, 47700.77993444352, 46779.535338383226]\n",
      "mean 49383.69343689459\n",
      "std 1875.7169739685507\n"
     ]
    }
   ],
   "source": [
    "cvs = cross_val_score(forest_reg,housing_prepared,housing_labels,\n",
    "                     scoring = 'neg_mean_squared_error',cv=10)\n",
    "\n",
    "show_tree(np.sqrt(-cvs))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 模型调参和网格搜索  \n",
    "[GridSearchCV官方文档](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html#sklearn.model_selection.GridSearchCV)  \n",
    "[博客](https://blog.csdn.net/weixin_41988628/article/details/83098130)  \n",
    "**GridSearchCV，它存在的意义就是自动调参，只要把参数输进去，就能给出最优化的结果和参数。但是这个方法适合于小数据集，一旦数据的量级上去了，很难得出结果。    \n",
    "数据量比较大的时候可以使用一个快速调优的方法——坐标下降。它其实是一种贪心算法：拿当前对模型影响最大的参数调优，直到最优化；再拿下一个影响最大的参数调优，如此下去，直到所有的参数调整完毕。这个方法的缺点就是可能会调到局部最优而不是全局最优，但是省时间省力**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=5, error_score='raise-deprecating',\n",
       "             estimator=RandomForestRegressor(bootstrap=True, criterion='mse',\n",
       "                                             max_depth=None,\n",
       "                                             max_features='auto',\n",
       "                                             max_leaf_nodes=None,\n",
       "                                             min_impurity_decrease=0.0,\n",
       "                                             min_impurity_split=None,\n",
       "                                             min_samples_leaf=1,\n",
       "                                             min_samples_split=2,\n",
       "                                             min_weight_fraction_leaf=0.0,\n",
       "                                             n_estimators=10, n_jobs=None,\n",
       "                                             oob_score=False, random_state=42,\n",
       "                                             verbose=0, warm_start=False),\n",
       "             iid='warn', n_jobs=None,\n",
       "             param_grid=[{'max_features': [3, 6, 9], 'n_estimators': [2, 4, 6]},\n",
       "                         {'bootstrap': [False], 'max_features': [10, 15],\n",
       "                          'n_estimators': [15, 16]}],\n",
       "             pre_dispatch='2*n_jobs', refit=True, return_train_score=True,\n",
       "             scoring='neg_mean_squared_error', verbose=0)"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.model_selection import GridSearchCV\n",
    "#每一个字典里的键值对会互相进行组合\n",
    "#n_estimators: 也就是弱学习器的最大迭代次数，或者说最大的弱学习器的个数，默认是10\n",
    "#bootstrap：默认True，是否有放回的采样。\n",
    "#max_features: RF划分时考虑的最大特征数。可以使用很多种类型的值，默认是\"None\",意味着划分时考虑所有的特征数\n",
    "param_grid = [\n",
    "    {'n_estimators':[2,4,6],'max_features':[3,6,9]},\n",
    "    {'n_estimators':[15,16],'bootstrap':[False],'max_features':[10,15]}\n",
    "]\n",
    "gridSearchCV = GridSearchCV(forest_reg,param_grid,cv= 5,\n",
    "                            scoring='neg_mean_squared_error', return_train_score=True)\n",
    "gridSearchCV.fit(housing_prepared,housing_labels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'bootstrap': False, 'max_features': 10, 'n_estimators': 16}"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gridSearchCV.best_params_\n",
    "#从给到的随机森林的参数组合，选出最好的参数组合"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "RandomForestRegressor(bootstrap=False, criterion='mse', max_depth=None,\n",
       "                      max_features=10, max_leaf_nodes=None,\n",
       "                      min_impurity_decrease=0.0, min_impurity_split=None,\n",
       "                      min_samples_leaf=1, min_samples_split=2,\n",
       "                      min_weight_fraction_leaf=0.0, n_estimators=16,\n",
       "                      n_jobs=None, oob_score=False, random_state=42, verbose=0,\n",
       "                      warm_start=False)"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gridSearchCV.best_estimator_\n",
    "#最好的估算器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "63541.034441522075 {'max_features': 3, 'n_estimators': 2}\n",
      "57229.08736808708 {'max_features': 3, 'n_estimators': 4}\n",
      "54522.65436936731 {'max_features': 3, 'n_estimators': 6}\n",
      "61745.54397179656 {'max_features': 6, 'n_estimators': 2}\n",
      "55024.48418176345 {'max_features': 6, 'n_estimators': 4}\n",
      "53012.217927345366 {'max_features': 6, 'n_estimators': 6}\n",
      "60490.73536146567 {'max_features': 9, 'n_estimators': 2}\n",
      "53822.46375884622 {'max_features': 9, 'n_estimators': 4}\n",
      "51956.366801775424 {'max_features': 9, 'n_estimators': 6}\n",
      "49866.238125412405 {'bootstrap': False, 'max_features': 10, 'n_estimators': 15}\n",
      "49696.31467712365 {'bootstrap': False, 'max_features': 10, 'n_estimators': 16}\n",
      "64475.943257420826 {'bootstrap': False, 'max_features': 15, 'n_estimators': 15}\n",
      "64467.887089117394 {'bootstrap': False, 'max_features': 15, 'n_estimators': 16}\n"
     ]
    }
   ],
   "source": [
    "gridSearchCV.best_params_\n",
    "#从给到的随机森林的参数组合，选出最好的参数组合\n",
    "gridSearchCV.best_estimator_\n",
    "#最好的估算器\n",
    "cvres = gridSearchCV.cv_results_\n",
    "cvres\n",
    "#取出所有组合的分数\n",
    "for mean_score,param in zip(cvres['mean_test_score'],cvres['params']):\n",
    "    print(np.sqrt(-mean_score),param)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 随机搜索"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "RandomizedSearchCV(cv=5, error_score='raise-deprecating',\n",
       "                   estimator=RandomForestRegressor(bootstrap=True,\n",
       "                                                   criterion='mse',\n",
       "                                                   max_depth=None,\n",
       "                                                   max_features='auto',\n",
       "                                                   max_leaf_nodes=None,\n",
       "                                                   min_impurity_decrease=0.0,\n",
       "                                                   min_impurity_split=None,\n",
       "                                                   min_samples_leaf=1,\n",
       "                                                   min_samples_split=2,\n",
       "                                                   min_weight_fraction_leaf=0.0,\n",
       "                                                   n_estimators=10, n_jobs=None,\n",
       "                                                   oob_score=False,\n",
       "                                                   random_state=4...\n",
       "                                                   warm_start=False),\n",
       "                   iid='warn', n_iter=10, n_jobs=None,\n",
       "                   param_distributions={'max_features': <scipy.stats._distn_infrastructure.rv_frozen object at 0x0000000018C85A58>,\n",
       "                                        'n_estimators': <scipy.stats._distn_infrastructure.rv_frozen object at 0x0000000018C85080>},\n",
       "                   pre_dispatch='2*n_jobs', random_state=42, refit=True,\n",
       "                   return_train_score=False, scoring='neg_mean_squared_error',\n",
       "                   verbose=0)"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.model_selection import RandomizedSearchCV\n",
    "from scipy.stats import randint\n",
    "param_random = {\n",
    "    'n_estimators':randint(low = 1,high = 200),\n",
    "    'max_features':randint(low =1,high = 13)\n",
    "}\n",
    "randomSearcCV = RandomizedSearchCV(forest_reg,param_distributions = param_random,\n",
    "                                  n_iter=10, cv=5, scoring='neg_mean_squared_error', random_state=42)\n",
    "\n",
    "randomSearcCV.fit(housing_prepared,housing_labels)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "47652.99561448863 {'max_features': 7, 'n_estimators': 180}\n",
      "47871.03272629438 {'max_features': 11, 'n_estimators': 72}\n",
      "48197.250414484086 {'max_features': 5, 'n_estimators': 103}\n",
      "47792.31176738279 {'max_features': 10, 'n_estimators': 75}\n",
      "47755.351215203445 {'max_features': 11, 'n_estimators': 88}\n",
      "48228.35627560164 {'max_features': 5, 'n_estimators': 100}\n",
      "47708.1275432768 {'max_features': 8, 'n_estimators': 152}\n",
      "48933.68899721294 {'max_features': 3, 'n_estimators': 150}\n",
      "61769.26267070222 {'max_features': 5, 'n_estimators': 2}\n",
      "47684.20737236529 {'max_features': 8, 'n_estimators': 158}\n"
     ]
    }
   ],
   "source": [
    "cvres = randomSearcCV.cv_results_\n",
    "cvres\n",
    "#取出所有组合的分数\n",
    "for mean_score,param in zip(cvres['mean_test_score'],cvres['params']):\n",
    "    print(np.sqrt(-mean_score),param)\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'max_features': 7, 'n_estimators': 180}"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "randomSearcCV.best_params_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**numpy中的argpartition()函数就是起的这个作用。对于传入的数组a，先用O(n)复杂度求出第k大的数字，然后利用这个第k大的数字将数组a划分成两半。\n",
    "此函数不对原数组进行操作，它只返回分区之后的下标。一般numpy中以arg开头的函数都是返回下标而不改变原数组。**\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 =   [10 12 16 11 13 19 14 18 15]\n",
      "1 =   [10 11 16 12 13 19 14 18 15]\n",
      "2 =   [10 11 12 16 13 19 14 18 15]\n",
      "3 =   [11 12 10 13 16 19 14 18 15]\n",
      "4 =   [11 12 10 13 14 15 19 18 16]\n",
      "5 =   [11 12 10 13 14 15 19 18 16]\n",
      "6 =   [11 12 10 13 14 15 16 18 19]\n",
      "7 =   [11 12 10 13 14 15 16 18 19]\n",
      "8 =   [11 12 10 13 14 15 16 18 19]\n"
     ]
    }
   ],
   "source": [
    "\n",
    "\n",
    "data = np.array([12, 10, 16, 11, 13, 19, 14, 18, 15])\n",
    "\n",
    "for i in range(len(data)):\n",
    "    print('%s =  '%i,data[np.argpartition(data,i)])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 作业三：流程合并 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Pipeline(memory=None,\n",
       "         steps=[('full_pipeline_predict',\n",
       "                 FeatureUnion(n_jobs=None,\n",
       "                              transformer_list=[('pipeline_num',\n",
       "                                                 Pipeline(memory=None,\n",
       "                                                          steps=[('getColumns1',\n",
       "                                                                  GetColumns(columns=Index(['index', 'longitude', 'latitude', 'housing_median_age', 'total_rooms',\n",
       "       'total_bedrooms', 'population', 'households', 'median_income',\n",
       "       'income_cat'],\n",
       "      dtype='object'))),\n",
       "                                                                 ('imputer',\n",
       "                                                                  I...\n",
       "                ('predict_random_tree',\n",
       "                 RandomForestRegressor(bootstrap=False, criterion='mse',\n",
       "                                       max_depth=None, max_features=10,\n",
       "                                       max_leaf_nodes=None,\n",
       "                                       min_impurity_decrease=0.0,\n",
       "                                       min_impurity_split=None,\n",
       "                                       min_samples_leaf=1, min_samples_split=2,\n",
       "                                       min_weight_fraction_leaf=0.0,\n",
       "                                       n_estimators=16, n_jobs=None,\n",
       "                                       oob_score=False, random_state=42,\n",
       "                                       verbose=0, warm_start=False))],\n",
       "         verbose=False)"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\n",
    "\n",
    "full_pipeline_predict = Pipeline([\n",
    "    ('full_pipeline_predict',full_pipeline),\n",
    "    ('predict_random_tree',RandomForestRegressor(random_state = 42,**gridSearchCV.best_params_))\n",
    "])\n",
    "\n",
    "full_pipeline_predict.fit(housing,housing_labels)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>310300.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>193800.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>113400.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>87500.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>216800.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          0\n",
       "0  310300.0\n",
       "1  193800.0\n",
       "2  113400.0\n",
       "3   87500.0\n",
       "4  216800.0"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "full_predict = full_pipeline_predict.predict(housing)\n",
    "pd.DataFrame(full_predict).head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "cvs = cross_val_score(full_pipeline_predict,housing,housing_labels,\n",
    "                     scoring = 'neg_mean_squared_error',cv=10)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "score [48770.43891033737, 50266.45559752187, 48326.52620821684, 48038.305712339396, 47577.132967473735, 52168.13460807454, 46778.185982992225, 49553.73910447228, 48177.63242294019, 46603.97838328191]\n",
      "mean 48626.05298976503\n",
      "std 1592.4379827668652\n"
     ]
    }
   ],
   "source": [
    "show_tree(np.sqrt(-cvs))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 作业二：将选出的最佳特征加入流程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>median_house_value</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>median_house_value</th>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>median_income</th>\n",
       "      <td>0.687210</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>income_cat</th>\n",
       "      <td>0.666744</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>latitude</th>\n",
       "      <td>-0.144648</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>total_rooms</th>\n",
       "      <td>0.132966</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>housing_median_age</th>\n",
       "      <td>0.115026</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>index</th>\n",
       "      <td>0.070924</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>households</th>\n",
       "      <td>0.067527</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>total_bedrooms</th>\n",
       "      <td>0.050532</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>longitude</th>\n",
       "      <td>-0.045510</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>population</th>\n",
       "      <td>-0.023436</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                    median_house_value\n",
       "median_house_value            1.000000\n",
       "median_income                 0.687210\n",
       "income_cat                    0.666744\n",
       "latitude                     -0.144648\n",
       "total_rooms                   0.132966\n",
       "housing_median_age            0.115026\n",
       "index                         0.070924\n",
       "households                    0.067527\n",
       "total_bedrooms                0.050532\n",
       "longitude                    -0.045510\n",
       "population                   -0.023436"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class Screen_best_feature(BaseEstimator,TransformerMixin):\n",
    "    \n",
    "    def __init__(self,label):\n",
    "        '''\n",
    "        label:标签列\n",
    "        '''\n",
    "        self.label = label\n",
    "        \n",
    "    def sort_by_abs(self,chara_relation):\n",
    "        '''\n",
    "        将series的值取绝对值作为新增的列\n",
    "        然后对新增的绝对值得列进行排序，删除该列\n",
    "        '''\n",
    "        chara_frame = chara_relation.to_frame()\n",
    "        chara_frame['abs']  = chara_relation.apply(abs)\n",
    "        return chara_frame.sort_values(by=['abs'],ascending = False).drop('abs',axis = 1)\n",
    "    \n",
    "    def fit(self,base_housing,y = None):\n",
    "        return self\n",
    "    \n",
    "    def transform(self,base_data,y = None):\n",
    "        complete_data = base_data.copy()\n",
    "        if isinstance(base_data,np.ndarray):\n",
    "            complete_data = pd.DataFrame(complete_data)\n",
    "        complete_data[self.label.name] = self.label\n",
    "        corr_data =  complete_data.corr()\n",
    "        return self.sort_by_abs(corr_data[self.label.name])\n",
    "    \n",
    "screen_best_feature = Screen_best_feature(housing_labels)\n",
    "chara_relation = screen_best_feature.fit_transform(housing)\n",
    "chara_relation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>median_house_value</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>median_house_value</th>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>median_income</th>\n",
       "      <td>0.687210</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>income_cat</th>\n",
       "      <td>0.666744</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bedrooms_per_rooms</th>\n",
       "      <td>-0.249659</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bedrooms_per_room</th>\n",
       "      <td>0.202367</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>rooms_per_household</th>\n",
       "      <td>0.145834</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>latitude</th>\n",
       "      <td>-0.144648</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>total_rooms</th>\n",
       "      <td>0.132966</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>housing_median_age</th>\n",
       "      <td>0.115026</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>index</th>\n",
       "      <td>0.070924</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>households</th>\n",
       "      <td>0.067527</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>total_bedrooms</th>\n",
       "      <td>0.050532</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>longitude</th>\n",
       "      <td>-0.045510</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>population_per_household</th>\n",
       "      <td>-0.026643</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>population</th>\n",
       "      <td>-0.023436</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                          median_house_value\n",
       "median_house_value                  1.000000\n",
       "median_income                       0.687210\n",
       "income_cat                          0.666744\n",
       "bedrooms_per_rooms                 -0.249659\n",
       "bedrooms_per_room                   0.202367\n",
       "rooms_per_household                 0.145834\n",
       "latitude                           -0.144648\n",
       "total_rooms                         0.132966\n",
       "housing_median_age                  0.115026\n",
       "index                               0.070924\n",
       "households                          0.067527\n",
       "total_bedrooms                      0.050532\n",
       "longitude                          -0.045510\n",
       "population_per_household           -0.026643\n",
       "population                         -0.023436"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "relation_pipeline = Pipeline([\n",
    "    ('combar1',CombineAttributes()),\n",
    "    ('screen_best_feature1',Screen_best_feature(label = housing_labels))\n",
    "                        \n",
    "])\n",
    "relation_pipeline.fit_transform(housing)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 作业四：使用GridSearchCV自动搜索‘bedrooms_per_room’ 合成特征是否应该合并到训练集中 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "RandomizedSearchCV(cv=5, error_score='raise-deprecating',\n",
       "                   estimator=Pipeline(memory=None,\n",
       "                                      steps=[('full_pipeline_predict',\n",
       "                                              FeatureUnion(n_jobs=None,\n",
       "                                                           transformer_list=[('pipeline_num',\n",
       "                                                                              Pipeline(memory=None,\n",
       "                                                                                       steps=[('getColumns1',\n",
       "                                                                                               GetColumns(columns=Index(['index', 'longitude', 'latitude', 'housing_median_age', 'total_rooms',\n",
       "       'total_bedrooms', 'population', 'househ...\n",
       "                   param_distributions={'full_pipeline_predict__pipeline_num__combina__dividend_indexs': <scipy.stats._distn_infrastructure.rv_frozen object at 0x00000000189FBD68>,\n",
       "                                        'full_pipeline_predict__pipeline_num__combina__divisor_indexs': <scipy.stats._distn_infrastructure.rv_frozen object at 0x00000000189FB2E8>},\n",
       "                   pre_dispatch='2*n_jobs', random_state=42, refit=True,\n",
       "                   return_train_score=False, scoring='neg_mean_squared_error',\n",
       "                   verbose=0)"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\n",
    "#解题思路：将所有合成特征的列名组成一个数组，通过随机搜索，依次取出所有的列名，查看特征组合的情况进行取舍\n",
    "from scipy.stats import randint\n",
    "divi_s = transfrom_columns_to_index(\"total_rooms\", \"total_bedrooms\", \"population\", \"households\")\n",
    "\n",
    "\n",
    "param_compost = {\n",
    "    'full_pipeline_predict__pipeline_num__combina__dividend_indexs':randint(low = 1,high =15),\n",
    "    'full_pipeline_predict__pipeline_num__combina__divisor_indexs':randint(low = 1,high = 15),\n",
    "}\n",
    "# combinaCV = GridSearchCV(pipeline_num,param_compost)\n",
    "combinaCV = RandomizedSearchCV(full_pipeline_predict,param_distributions = param_compost,\n",
    "                                  n_iter=10, cv=5, scoring='neg_mean_squared_error', random_state=42)\n",
    "combinaCV.fit(housing,housing_labels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "49621.30260562171 {'full_pipeline_predict__pipeline_num__combina__dividend_indexs': 7, 'full_pipeline_predict__pipeline_num__combina__divisor_indexs': 4}\n",
      "49621.30260562171 {'full_pipeline_predict__pipeline_num__combina__dividend_indexs': 13, 'full_pipeline_predict__pipeline_num__combina__divisor_indexs': 11}\n",
      "49621.30260562171 {'full_pipeline_predict__pipeline_num__combina__dividend_indexs': 8, 'full_pipeline_predict__pipeline_num__combina__divisor_indexs': 13}\n",
      "49621.30260562171 {'full_pipeline_predict__pipeline_num__combina__dividend_indexs': 5, 'full_pipeline_predict__pipeline_num__combina__divisor_indexs': 7}\n",
      "49621.30260562171 {'full_pipeline_predict__pipeline_num__combina__dividend_indexs': 10, 'full_pipeline_predict__pipeline_num__combina__divisor_indexs': 3}\n",
      "49621.30260562171 {'full_pipeline_predict__pipeline_num__combina__dividend_indexs': 7, 'full_pipeline_predict__pipeline_num__combina__divisor_indexs': 11}\n",
      "49621.30260562171 {'full_pipeline_predict__pipeline_num__combina__dividend_indexs': 11, 'full_pipeline_predict__pipeline_num__combina__divisor_indexs': 8}\n",
      "49621.30260562171 {'full_pipeline_predict__pipeline_num__combina__dividend_indexs': 5, 'full_pipeline_predict__pipeline_num__combina__divisor_indexs': 4}\n",
      "49621.30260562171 {'full_pipeline_predict__pipeline_num__combina__dividend_indexs': 8, 'full_pipeline_predict__pipeline_num__combina__divisor_indexs': 8}\n",
      "49621.30260562171 {'full_pipeline_predict__pipeline_num__combina__dividend_indexs': 3, 'full_pipeline_predict__pipeline_num__combina__divisor_indexs': 6}\n"
     ]
    }
   ],
   "source": [
    "combina_cvre = combinaCV.cv_results_\n",
    "# housing_num.columns\n",
    "#取出所有组合的分数\n",
    "for mean_score,param in zip(combina_cvre['mean_test_score'],combina_cvre['params']):\n",
    "    print(np.sqrt(-mean_score),param)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
